#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/freezer.h>

struct task_struct *monitor_thread;

static int monitor_fn(void)
{
    struct task_struct *g, *p;

    for_each_process_thread(g, p) {
        bool is_kthread = p->flags & PF_KTHREAD;
        bool is_nofreeze = p->flags & PF_NOFREEZE;
        if (p->exit_state == EXIT_ZOMBIE)
            pr_info("Process %s [%d] %s slow_path:%d nofreeze:%d\n",
                    p->comm, p->pid, is_kthread == 1 ? "kthread":"userthread",
                    freezing_slow_path(p), is_nofreeze);

    }
    return 0;
}


static int __init freeze_monitor_init(void)
{
    pr_info("Freeze monitor module inited\n");
    monitor_fn();
    return 0;
}

static void __exit freeze_monitor_exit(void)
{
    pr_info("Freeze monitor module exited\n");
}

module_init(freeze_monitor_init);
module_exit(freeze_monitor_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zzhwaxy");
MODULE_DESCRIPTION("Monitor process state during freeze");

